// This class is used to temporarily store and retrieve the all Tasks that user requires. 
//Tasks from stored session in .txt file are populated into stroage up first 
//starting O.L Planner. Storage class is called by Logic class to perform various
//commands on tasks.
//
//This class supports the following commands:
//  1. add tasks and the tasks will be sorted accoding to dates automatically;
//	2. delete tasks;
//	3. search tasks by key words;
//  4. display by taks type;
//	5. display by dates;
//	6. display by task status 
//  7. mofify title/ date / start time / end time;
//  8. undo;
//	9. mark task as Complete;
 
#ifndef STORAGE_H_
#define STORAGE_H_

#include <string>
#include <vector>
#include <stdio.h>   
#include <assert.h>
#include <algorithm>
#include "Task.h"
#include "Parser.h"
#include "InvalidInputException.h"
#include "Logger.h"
#include "Utility.h"

#define MESSAGE_ADDED "Added"
#define MESSAGE_DELETED "Deleted"
#define MESSAGE_MODIFIED "Modified"
#define MESSAGE_COMPLETED "Completed"

using namespace std;
static char buffer[255];

class Storage {
public:
	static const QString MESSAGE_EMPTY_STORAGE;
	static const QString MESSAGE_CONFLICTING_MEETING;
	static const string MESSAGE_FLOATING;
    static const string MESSAGE_DEADLINE;
	static const string MESSAGE_MEETING;
    static const string MESSAGE_EVENT;

	enum CommandType {
		ADD, DELETE, DISPLAY, COMPLETE, MODIFY, CLEAR, UNDO, SAVE, SEARCH, EXIT, INVALID
	};

	enum Component {
		TITLE, STARTDATE, ENDDATE, STARTTIME, ENDTIME, TAGS, INVALIDCOMPONENT
	};

private:
	QVector<Task> taskStorage;
	QVector<CommandType> history;
	QVector<Task> storeLastTask;
	Parser parser;
	Utility util;
    Logger storageLogger;

	//Functions related to storing tasks in sequential order
	void storeTask(Task addTask);
	bool compareDateAndTime(Task storedTask, Task addTask);
	void extractTaskParam(Task task, QDate &date, QTime &time);
	
	void compileUserFeedback(CommandType command, Task feedbackTask, QString &userFeedback);
	QString collectTaskDetails(string command, Task task);
	
	QString undoModify();
	QString undoComplete();

	bool isConflict(Task addTask);	
	int searchTaskIndex(int refNum);
	Component determineComponent(QString component);
	QVector<Task> taskWithKeyword(QString keyword);
	QVector<Task> taskWithTags(QString keyword);

public:
	Storage();
	~Storage();
	QString addCommand(Task addTitle);
	QString deleteCommand(int taskNum);
	QString undoCommand();
	QString modifyCommand(int refNum, QString component, QString modifiedContent);
	QString markComplete(int refNum);
	QVector<Task> searchCommand(QString keyword);
	QVector<Task> searchTagsCommand(QString keyword);

	//Functions that retrieve tasks according to particular task parameters
	QVector<Task> displayDate(QDate date);
	QVector<Task> displayEvent();
	QVector<Task> displayMeeting();
	QVector<Task> displayDeadline();
	QVector<Task> displayFloating();
	QVector<Task> displayAll();

	//Functions that retrieve tasks according to their task statuses
	QVector<Task> checkOverdue();
	QVector<Task> checkApproaching();
};

#endif
